"""
This file demonstrates two different styles of tests (one doctest and one
unittest). These will both pass when you run "manage.py test".

Replace these with more appropriate tests for your application.
"""

from django.test import TestCase
from pyceab.course.models import Course



class CourseQueryTest(TestCase):
    fixtures = ['courses.json']

    def assertResultsetsEqual(self, set_a, set_b):
        results_a = [result for result in set_a]
        results_b = [result for result in set_b]
        self.assertEquals(results_a, results_b)

    def assertResultsetsNotEqual(self, set_a, set_b):
        results_a = [result for result in set_a]
        results_b = [result for result in set_b]
        self.assertNotEqual(results_a, results_b)

    def testAllCourses(self):
        all_courses = Course.objects.all()
        response = self.client.get('/courses/')
        self.assertResultsetsEqual(all_courses, response.context['courses'])

    def testSydeCourses(self):
        syde_courses = Course.objects.filter(department='SYDE')
        response = self.client.get('/courses/?department=SYDE')

        self.assertResultsetsEqual(syde_courses, response.context['courses'])

    def testSyCourses(self):
        sy_courses = Course.objects.filter(department__contains='SY')
        response = self.client.get('/courses/?department=SY&department_operator=contains')
        self.assertResultsetsEqual(sy_courses, response.context['courses'])

    def testCseCourses(self):
        cses = {}
        cses['a'] = Course.objects.filter(cse_a__gt=0)
        cses['b']= Course.objects.filter(cse_b__gt=0)
        cses['c']= Course.objects.filter(cse_c__gt=0)
        cses['d']= Course.objects.filter(cse_d__gt=0)

        list_types = ['a', 'b', 'c', 'd']
        for list_type in list_types:
            response = self.client.get('/courses/?cse_%(list_type)s=0&cse_%(list_type)s_operator=gt' % {'list_type': list_type})
            self.assertResultsetsEqual(cses[list_type], response.context['courses'])

    def testOffered(self):
        offered_winter = Course.objects.filter(offered_winter=True)
        offered_not_winter = Course.objects.filter(offered_winter=False)
        response = self.client.get('/courses/?offered_winter=1')
        self.assertResultsetsEqual(offered_winter, response.context['courses'])
        response = self.client.get('/courses/?offered_winter=0')
        self.assertResultsetsEqual(offered_not_winter, response.context['courses'])

    def testTeCourses(self):
        maths = Course.objects.filter(te_math__gt=0)
        response = self.client.get('/courses/?te_math=0&te_math_operator=gt')
        self.assertResultsetsEqual(maths, response.context['courses'])


    def testMultipleCriteria(self):
        cs_and_science = Course.objects.filter(department__iexact='cs', te_sci__gt=0)
        math_and_design = Course.objects.filter(te_math__gt=0, te_engdes__gt=0)
        syde_and_design = Course.objects.filter(department__iexact='syde', te_engdes__gt=0)

        response = self.client.get('/courses/?department=cs&department_operator=iexact&te_sci=0&te_sci_operator=gt')
        self.assertResultsetsEqual(cs_and_science, response.context['courses'])
        self.assertResultsetsNotEqual(math_and_design, response.context['courses'])
        response = self.client.get('/courses/?te_engdes=0&te_engdes_operator=gt&te_math=0&te_math_operator=gt')
        self.assertResultsetsEqual(math_and_design, response.context['courses'])
        self.assertResultsetsNotEqual(syde_and_design, response.context['courses'])
        response = self.client.get('/courses/?department=syde&department_operator=iexact&te_engdes=0&te_engdes_operator=gt')
        self.assertResultsetsEqual(syde_and_design, response.context['courses'])
        self.assertResultsetsNotEqual(math_and_design, response.context['courses'])

    def testSimpleSearch(self):
        optimization = Course.objects.filter(full_name__icontains='optimization')
        response = self.client.get('/courses/?simple_search=optimization')
        self.assertResultsetsEqual(optimization, response.context['courses'])

        sy_5 = Course.objects.filter(department__icontains='sy', course_code__icontains='5')
        response = self.client.get('/courses/?simple_search=sy 5')
        self.assertResultsetsEqual(sy_5, response.context['courses'])

        response = self.client.get('/courses/?simple_search=sy5')
        self.assertResultsetsEqual(sy_5, response.context['courses'])


    def testSingleOperator(self):
        maths = Course.objects.filter(te_math__gt=0)
        all = Course.objects.all()
        response = self.client.get('/courses/?te_math__gt=0')
        self.assertResultsetsEqual(maths, response.context['courses'])

        # filter is improper so should get no filtering effect
        response = self.client.get('/courses/?te_math__gta=0')
        self.assertResultsetsEqual(all, response.context['courses'])
